package library.multiple_pictures_selector;

import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.provider.MediaStore;
import android.support.v7.app.AlertDialog;
import android.widget.Toast;

import java.io.File;
import java.util.Objects;

import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;
import library.common.util.FileUtils;
import library.common.util.ToastUtils;
import library.multiple_pictures_selector.engine.impl.GlideEngine;
import library.multiple_pictures_selector.filter.Filter;
import library.multiple_pictures_selector.filter.GifSizeFilter;

/**
 * @author Created by qiang.hou on 2018/7/13.
 * @version 1.0
 */
public class MultiPictureSelector {
    public static final int CODE_FOR_GET_PICTURE_ALBUM = 10002;
    public static final int CODE_FOR_GET_PICTURE_CAMERA = 10001;

    private MultiPictureSelector() {
    }

    private static class InstanceHolder {
        static MultiPictureSelector mInstance = new MultiPictureSelector();
    }

    public static MultiPictureSelector getInstance() {
        return InstanceHolder.mInstance;
    }

    /**
     * get image method
     *
     * @param activity              Activity
     * @param fileProviderAuthority Authority
     * @param availableCount        max image count
     */
    public void getImage(final Activity activity, final String fileProviderAuthority, final int availableCount) {
        if (null == activity) {
            return;
        }
        showChooseView(activity, new OnChooseItemListener() {

            @Override
            public void onItemTakePicture() {
                getPictureFromCamera(activity, fileProviderAuthority);
            }

            @Override
            public void onItemFromPhotoAlbum() {
                getPictureFromGallery(activity, availableCount);
            }
        });
    }

    /**
     * show dialog to choose style of getting picture
     *
     * @param context              Context
     * @param onChooseItemListener OnChooseItemListener
     */
    private void showChooseView(Context context, final OnChooseItemListener onChooseItemListener) {
        AlertDialog.Builder dialog = new AlertDialog.Builder(context).setItems(
                context.getResources().getStringArray(R.array.choose_img_array),
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        if (onChooseItemListener != null) {
                            if (which == 0) {
                                //拍照
                                onChooseItemListener.onItemTakePicture();
                            } else if (which == 1) {
                                //从手机相册选取
                                onChooseItemListener.onItemFromPhotoAlbum();
                            }
                        }
                    }
                }).setOnCancelListener(new DialogInterface.OnCancelListener() {
            @Override
            public void onCancel(DialogInterface dialog) {
                if (onChooseItemListener != null && onChooseItemListener instanceof OnChooseItemAndCancelListener) {
                    ((OnChooseItemAndCancelListener) onChooseItemListener).onItemCancel();
                }
            }
        });
        dialog.show();
    }

    /**
     * get picture from camera
     *
     * @param activity              Activity
     * @param fileProviderAuthority Authority
     */
    private void getPictureFromCamera(final Activity activity, final String fileProviderAuthority) {
        new RxPermissions(activity).request(Manifest.permission.CAMERA)
                .subscribe(new Observer<Boolean>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(Boolean aBoolean) {
                        if (aBoolean) {
                            String cameraPhotoName = System.currentTimeMillis() + "pic.jpg";
                            File cacheFile = new File(Objects.requireNonNull(activity.getExternalFilesDir("files")).getPath() + File.separator + cameraPhotoName);
                            Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                            intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
                            intent.putExtra(MediaStore.EXTRA_OUTPUT,
                                    (fileProviderAuthority == null || fileProviderAuthority.equals(""))
                                            ? FileUtils.getProviderUri(activity, cacheFile)
                                            : FileUtils.getProviderUri(activity, fileProviderAuthority, cacheFile));
                            activity.startActivityForResult(intent, CODE_FOR_GET_PICTURE_CAMERA);
                        } else {
                            ToastUtils.showToast(activity, activity.getResources().getString(R.string.grant_fail_title), Toast.LENGTH_LONG);
                        }
                    }

                    @Override
                    public void onError(Throwable e) {
                        ToastUtils.showToast(activity, activity.getResources().getString(R.string.grant_fail_title), Toast.LENGTH_LONG);
                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }

    /**
     * get picture from album
     *
     * @param activity       Activity
     * @param availableCount available count
     */
    private void getPictureFromGallery(final Activity activity, final int availableCount) {
        new RxPermissions(activity).request(Manifest.permission.WRITE_EXTERNAL_STORAGE)
                .subscribe(new Observer<Boolean>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(Boolean aBoolean) {
                        if (aBoolean) {
                            Matisse.from(activity)
                                    .choose(MimeType.ofImage())
                                    .theme(R.style.Matisse)
                                    .countable(false)
                                    .addFilter(new GifSizeFilter(320, 320, 5 * Filter.K * Filter.K))
                                    .maxSelectable(availableCount)
                                    .originalEnable(true)
                                    .maxOriginalSize(1)
                                    .imageEngine(new GlideEngine())
                                    .forResult(CODE_FOR_GET_PICTURE_ALBUM);
                        } else {
                            ToastUtils.showToast(activity, activity.getResources().getString(R.string.grant_fail_title), Toast.LENGTH_LONG);
                        }
                    }

                    @Override
                    public void onError(Throwable e) {
                        ToastUtils.showToast(activity, activity.getResources().getString(R.string.grant_fail_title), Toast.LENGTH_LONG);
                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }

    public interface OnChooseItemListener {
        void onItemTakePicture();

        void onItemFromPhotoAlbum();
    }

    public interface OnChooseItemAndCancelListener {
        void onItemCancel();
    }
}
